﻿#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define SIZE 5
#define _Success_ 1 //成功
#define _fail_ 2 //失败
#define _error_ 3//不知名错误

struct listnode {
	char  data[5] ;
	struct listnode *nextptr;

};
typedef struct listnode Listnode;
typedef Listnode *listnodeptr;

typedef  int Handler;

bool is_digit(char *s1)//确定是数字
{
	while (*s1 != '\0')
	{
		if (isalpha(*s1))
		{
			return false;
			
		}
		s1++;
	}
	return true;
}

int stradd(char * s1)//数字相加
{
	int add = 0;
	while (*s1 != '\0')
	{
		add += *s1;
		s1++;
	}
	return add;
}

bool is_big(char *s1, char *s2)//判断是否较大
{

		if ((is_digit(s1)&&is_digit(s2)))
	{
		if (stradd(s1)>stradd(s2))
		{
			return true;
		}
		else
		return false;
	}
	else if (strcmp(s1, s2) > 0)
	{
		return true;
	}
	else
	return false;
}

bool is_same(char *s1, char*s2)//判断是否一样
{
	if (strcmp(s1, s2) == 0)
	{
		return true;
	}
	return false;
}

listnodeptr making(void)//分配内存空间函数
{
	 listnodeptr newptr = (listnodeptr)malloc(sizeof(Listnode));
	 return newptr;
}



listnodeptr jubing_int(Handler bingju)//将int变为表地址
{
	return (listnodeptr)bingju;
}

Handler jubing_handler(listnodeptr a)//将表地址变为int
{
	return (Handler)a;
}


typedef void(*action)(char *);
void Foreach(Handler star, action fp)//遍历输出表
{
	listnodeptr currentptr = jubing_int(star);
	while (currentptr != NULL &&currentptr->data != NULL)
	{
		fp(currentptr->data);
		currentptr = currentptr->nextptr;
	}
	

}

Handler Create(void)//对外内存地址函数,外
{
	listnodeptr  star = making();
	memset(star->data, NULL, sizeof(star->data));
	star->nextptr = NULL;
	return jubing_handler(star);
}

typedef  int insertResult;
insertResult insert(Handler sptr, char* value)//插入和新建链表
{
	listnodeptr head = jubing_int(sptr);

	if (head != NULL)//当有内存空间时
	{
		//printf("%s", value);
		listnodeptr newsptr = making();
		if (newsptr != NULL)
		{
			strcpy(newsptr->data, value);//为新表赋值表的编号
			//newsptr->nextptr = NULL;//尾地址为NULL

			listnodeptr previousptr = NULL;//保存路标
			listnodeptr currentptr = head;//用来循环的查找头地址
										//以上用来插入查找循环

			while (currentptr != NULL && is_big( value, currentptr->data))//当没从头地址循环到最尾NULL时，以及新编号大于大于旧编号时
			{
				previousptr = currentptr;//保存路标
				currentptr = currentptr->nextptr;//进入下一层链表
			}
			if (previousptr == NULL)//当没有进行循环（第一个表，或者链表编号数值最小）
			{

				if ((currentptr != NULL && *value != *currentptr->data) || head->nextptr == NULL)//当遍历没有结束并且新编号没有重复，或者遍历结束
				{
					if (head->nextptr != NULL)
					{
						char str[SIZE];
						strcpy(str, head->data);//头地址的数据与后一个互换，确保句柄不变
						strcpy(head->data, newsptr->data);
						strcpy(newsptr->data, str);
						newsptr->nextptr = head->nextptr;
						head->nextptr = newsptr;
					}
					else//只有头地址，后面为空的情况
					{
						strcpy( head->data,value);
						head->nextptr = NULL;
					}
					return _Success_;//成功
				}
				else
				{
					return _fail_;//重复字母或数字
				}
			}
			else//需要插入
			{
				if ((currentptr != NULL && value != currentptr->data) || currentptr == NULL)//当遍历没有结束并且新编号没有重复，或者遍历结束
				{
					previousptr->nextptr = newsptr;//将新编号的地址放入刚刚（最小于）小于他的地址的尾巴
					newsptr->nextptr = currentptr;//将新编号地址的尾巴指向刚刚大于他的链表地址
					return _Success_;//成功
				}
				else
				{
					return _fail_;//重复字母或数字
				}

			}

		}
		else
		{
			return _error_;//内存空间不够

		}

	}
	else
	{
		return _error_;
	}
}




typedef  int deleteResult;
deleteResult dele(Handler sptr, char * value)//删除函数，delete，因为撞关键词所以改了
{
	listnodeptr head = jubing_int(sptr);
	if (head != NULL)
	{
		if (is_same(value, head->data))//当输入值等于链表头部编号时
		{
			
			if (head->nextptr != NULL)
			{
				listnodeptr temptr = head->nextptr;
				strcpy(head->data, temptr->data);
				head->nextptr = temptr->nextptr;
				free(temptr);
			}//将后一个数据与头地址数据互换，李代桃僵，删除后一个数据
			
		}
		else
		{
			listnodeptr previousptr = head;//保存地址
			listnodeptr currentptr =head->nextptr;//寻找地址
													 //循环查找
			while (currentptr != NULL && !is_same(currentptr->data, value))//当循环没到最尾，或者链表层中编号不等于输入值时
			{
				previousptr = currentptr;//保存地址
				currentptr = currentptr->nextptr;//进入下一层链表
			}
			if (currentptr != NULL)//找到时
			{
				listnodeptr temptr = currentptr;
				previousptr->nextptr = currentptr->nextptr;//将前一个链表的尾巴指向查到的链表的下一个层的地址
				free(temptr);//释放内存
				return _Success_;
			}
			else{
				return _fail_;//找不到相关编号
			}	
		}
		
	}
	else
	{
		return _error_;//空列表
	}
}

bool IsEmpty(Handler handler)//当头文件是空时
{
	listnodeptr sptr = jubing_int(handler);
	return sptr == NULL;
}


